接續前篇的內容:
底下為前一篇的 nginx-deploy.yaml。
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploy
  labels:
    app: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: nginx
        image: nginx:1.20.0
        ports:
        - containerPort: 80
目的:將該應用程式的 container image 由 nginx:1.20.0 更新為 nginx:1.23.0。
開始前我先以 kubectl create -f nginx-deploy.yaml 來建立 deployment。先來看 2 個實用的指令:
kubectl rollout status
kubectl rollout history
第 1 個可以用來查看 rollout 狀態。
kubectl rollout status deployment/nginx-deploy
第 2 個可以查看 rollout 的 revision 與歷史紀錄。
kubectl rollout history deployment/nginx-deploy
待會使用以上 2 種指令來觀察 rollout 變化。
將 image 由 nginx:1.20.0 修改成 nginx:1.23.0,加上 --record 會在 rollout history 裡紀錄該指令。
可以使用 kubectl edit。
kubectl edit deployment nginx-deploy --record
deployment.apps/nginx-deploy edited
或是使用 kubectl set image。
kubectl set image deployment nginx-deploy nginx=nginx:1.23.0 --record
deployment.apps/nginx-deploy image updated
因目前的更新政策是 RollingUpdate,可以查看到 deployment 建立新的 nginx:1.23.0 pods,依序關閉舊的 nginx:1.20.0 pods,在此政策下版本更新並不會中斷應用程式的存取。
kubectl rollout status deployment/nginx-deploy
Waiting for deployment "nginx-deploy" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "nginx-deploy" rollout to finish: 1 old replicas are pending termination...
deployment "nginx-deploy" successfully rolled out
可以從 kubectl describe 裡查看 deployment 的 Events。
kubectl describe deploy nginx-deploy
Name:                   nginx-deploy
Namespace:              default
CreationTimestamp:      Tue, 26 Sep 2023 15:34:28 +0800
Labels:                 app=my-app
Annotations:            deployment.kubernetes.io/revision: 2
                        kubernetes.io/change-cause: kubectl edit deployment nginx-deploy --record=true
Selector:               app=my-app
Replicas:               3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=my-app
  Containers:
   nginx:
    Image:        nginx:1.23.0
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:   nginx-deploy-69d4d4678b (3/3 replicas created)
Events:
  Type    Reason             Age    From                   Message
  ----    ------             ----   ----                   -------
  Normal  ScalingReplicaSet  2m19s  deployment-controller  Scaled up replica set nginx-deploy-65b6d5d9d9 to 3
  Normal  ScalingReplicaSet  49s    deployment-controller  Scaled up replica set nginx-deploy-69d4d4678b to 1
  Normal  ScalingReplicaSet  48s    deployment-controller  Scaled down replica set nginx-deploy-65b6d5d9d9 to 2 from 3
  Normal  ScalingReplicaSet  48s    deployment-controller  Scaled up replica set nginx-deploy-69d4d4678b to 2 from 1
  Normal  ScalingReplicaSet  47s    deployment-controller  Scaled down replica set nginx-deploy-65b6d5d9d9 to 1 from 2
  Normal  ScalingReplicaSet  47s    deployment-controller  Scaled up replica set nginx-deploy-69d4d4678b to 3 from 2
  Normal  ScalingReplicaSet  46s    deployment-controller  Scaled down replica set nginx-deploy-65b6d5d9d9 to 0 from 1
另外可以從 kubectl rollout history 看到建立的 revision 是因為哪個指令產生的 (CHANGE-CAUSE)。第一行是一開始使用 kubectl create 建立 deployment 的指令,第二行是剛才輸入 kubectl edit 修改 image 的指令。
kubectl rollout history deployment/nginx-deploy
deployment.apps/nginx-deploy
REVISION  CHANGE-CAUSE
1         kubectl create --filename=nginx-deploy.yaml --record=true
2         kubectl edit deployment nginx-deploy --record=true
查看 pods 是否 ready。
kubectl get po
NAME                            READY   STATUS    RESTARTS   AGE
nginx-deploy-69d4d4678b-dj24t   1/1     Running   0          101s
nginx-deploy-69d4d4678b-tcbkn   1/1     Running   0          100s
nginx-deploy-69d4d4678b-z4gpb   1/1     Running   0          99s
目的:復原至應用程式的前一版,也就是將 image 由 nginx:1.23.0 回滾至 nginx:1.20.0。
使用 kubectl rollout undo。
kubectl rollout undo deployment/nginx-deploy
deployment.apps/nginx-deploy rolled back
觀察 k8s 正依序建立 nginx:1.20.0 新的 pods,並逐步關閉 nginx:1.23.0 舊的 pods,回復至 revision 1。
kubectl rollout status deployment/nginx-deploy
Waiting for deployment "nginx-deploy" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "nginx-deploy" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "nginx-deploy" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "nginx-deploy" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "nginx-deploy" rollout to finish: 1 old replicas are pending termination...
deployment "nginx-deploy" successfully rolled out
查看是否真的復原、其 image 應為 nginx:1.20.0。
kubectl describe deploy nginx-deploy
Name:                   nginx-deploy
Namespace:              default
CreationTimestamp:      Tue, 26 Sep 2023 15:34:28 +0800
Labels:                 app=my-app
Annotations:            deployment.kubernetes.io/revision: 3
                        kubernetes.io/change-cause: kubectl create --filename=nginx-deploy.yaml --record=true
Selector:               app=my-app
Replicas:               3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=my-app
  Containers:
   nginx:
    Image:        nginx:1.20.0
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:   nginx-deploy-65b6d5d9d9 (3/3 replicas created)
Events:
  Type    Reason             Age                From                   Message
  ----    ------             ----               ----                   -------
  Normal  ScalingReplicaSet  7m56s              deployment-controller  Scaled up replica set nginx-deploy-65b6d5d9d9 to 3
  Normal  ScalingReplicaSet  6m26s              deployment-controller  Scaled up replica set nginx-deploy-69d4d4678b to 1
  Normal  ScalingReplicaSet  6m25s              deployment-controller  Scaled down replica set nginx-deploy-65b6d5d9d9 to 2 from 3
  Normal  ScalingReplicaSet  6m25s              deployment-controller  Scaled up replica set nginx-deploy-69d4d4678b to 2 from 1
  Normal  ScalingReplicaSet  6m24s              deployment-controller  Scaled down replica set nginx-deploy-65b6d5d9d9 to 1 from 2
  Normal  ScalingReplicaSet  6m24s              deployment-controller  Scaled up replica set nginx-deploy-69d4d4678b to 3 from 2
  Normal  ScalingReplicaSet  6m23s              deployment-controller  Scaled down replica set nginx-deploy-65b6d5d9d9 to 0 from 1
  Normal  ScalingReplicaSet  31s                deployment-controller  Scaled up replica set nginx-deploy-65b6d5d9d9 to 1 from 0
  Normal  ScalingReplicaSet  30s                deployment-controller  Scaled down replica set nginx-deploy-69d4d4678b to 2 from 3
  Normal  ScalingReplicaSet  27s (x4 over 30s)  deployment-controller  (combined from similar events): Scaled down replica set nginx-deploy-69d4d4678b to 0 from 1
再執行以下指令。
kubectl rollout history deployment/nginx-deploy
deployment.apps/nginx-deploy
REVISION  CHANGE-CAUSE
2         kubectl edit deployment nginx-deploy --record=true
3         kubectl create --filename=nginx-deploy.yaml --record=true
可以看見 revision 3,但 revision 1 不見了。
事實上當前的 revision 3 的內容就是 revision 1,意思是退回的 revision 1 被變更成最新的 revision 並將其名子更改為 revision 3。
執行以下指令刪除 deployment。
kubectl delete deploy nginx-deploy
deployment.apps "nginx-deploy" deleted
查看 deployment、replicaset 及 pod。
kubectl get deploy
No resources found in default namespace.
kubectl get rs,po
No resources found in default namespace.